home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / Misc / DXinstall / dxinstall.cpp < prev    next >
C/C++ Source or Header  |  2001-10-31  |  15KB  |  421 lines

  1. //-----------------------------------------------------------------------------
  2. // File: DxInstall.cpp
  3. //
  4. // Desc: Example code showing how to use DirectXSetup.
  5. //
  6. //       This file contains code that will handle all messages sent to the
  7. //       DirectXSetupCallbackFunction, with the filtering level set at what the
  8. //       user wants.  This way you can test to see which messages you want to
  9. //       h andle automatically or pass on to the user.
  10. //
  11. //       Call Tree:
  12. //          DirectXInstallWndProc         See WINCODE.CPP
  13. //             DirectXInstall             Set up the callback and handle return codes
  14. //                 GetReply               See WINCODE.CPP
  15. //             DirectXGetVersion          Display the results of DirectXSetupGetVersion()
  16. //          DirectXSetupCallbackFunction  Called from DirectXSetup
  17. //             GetReply                   See WINCODE.CPP
  18. //             SetButtons                 See WINCODE.CPP
  19. //                ShowButton              See WINCODE.CPP
  20. //
  21. // Copyright (c) 1998-2001 Microsoft Corporation. All rights reserved.
  22. //-----------------------------------------------------------------------------
  23. #include <windows.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <dsetup.h>
  27. #include "resource.h"
  28. #include "DXInstall.h"
  29.  
  30.  
  31.  
  32.  
  33. //-----------------------------------------------------------------------------
  34. // Externs for global variables
  35. //-----------------------------------------------------------------------------
  36. extern DWORD        g_dwStatus;         // Filter setting for messages from DirectXSetup
  37. extern HINSTANCE    g_hInstance;        // Global instance handle
  38. extern HWND         g_hDlg;             // Window handle to dialog proc
  39. extern CHAR         g_strAppTitle[256]; // Application title
  40. extern INT          g_iReply;           // Global value for dialog return
  41. extern BOOL         g_bCheckOlder;      // Whether or not to check for older installs
  42.  
  43.  
  44.  
  45.  
  46. //-----------------------------------------------------------------------------
  47. // Name: GetReply()
  48. // Desc: Waits for the user to click on a button on our simulated message box
  49. //       See DlgProc for the code that sets g_wReply
  50. //-----------------------------------------------------------------------------
  51. DWORD GetReply( DWORD dwMsgType )
  52. {
  53.     DWORD dwDefaultButton = 0;
  54.  
  55.     // Wait until DlgProc() lets us know that the user clicked on a button
  56.     while( g_iReply == -1 )
  57.     {
  58.         MSG msg;
  59.  
  60.         // Forward my messages...
  61.         while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  62.         {
  63.             if( msg.message == WM_QUIT       ||
  64.                 msg.message == WM_CLOSE      ||
  65.                 msg.message == WM_SYSCOMMAND ||
  66.                 msg.message == WM_DESTROY )
  67.             {
  68.                 // Put the message back on the queue and get out of here.
  69.                 PostMessage( msg.hwnd, msg.message, msg.wParam, msg.lParam );
  70.                 break;
  71.             }
  72.             if( !IsDialogMessage( msg.hwnd, &msg ) )
  73.             {
  74.                 TranslateMessage( &msg );
  75.                 DispatchMessage( &msg );
  76.             }
  77.         }
  78.     }
  79.  
  80.     // Return the proper ID value for the button the user clicked on
  81.     // This code simulates what MessageBox() would return
  82.     switch( dwMsgType & 0x0000000F )
  83.     {
  84.         case MB_OKCANCEL:
  85.             dwDefaultButton = (g_iReply==IDBUT1) ? IDOK : IDCANCEL;
  86.             break;
  87.  
  88.         case MB_OK:
  89.             dwDefaultButton = IDOK;
  90.             break;
  91.  
  92.         case MB_RETRYCANCEL:
  93.             dwDefaultButton = (g_iReply==IDBUT1) ? IDRETRY : IDCANCEL;
  94.             break;
  95.  
  96.         case MB_ABORTRETRYIGNORE:
  97.             if( g_iReply == IDBUT1 )
  98.                 dwDefaultButton = IDABORT;
  99.             else if (g_iReply == IDBUT2)
  100.                 dwDefaultButton = IDRETRY;
  101.             else
  102.                 dwDefaultButton = IDIGNORE;
  103.             break;
  104.  
  105.         case MB_YESNOCANCEL:
  106.             if( g_iReply == IDBUT1 )
  107.                 dwDefaultButton = IDYES;
  108.             else if( g_iReply == IDBUT2 )
  109.                 dwDefaultButton = IDNO;
  110.             else
  111.                 dwDefaultButton = IDCANCEL;
  112.             break;
  113.  
  114.         case MB_YESNO:
  115.             dwDefaultButton = (g_iReply==IDBUT1) ? IDYES : IDNO;
  116.             break;
  117.  
  118.         default:
  119.             dwDefaultButton = IDOK;
  120.     }
  121.  
  122.     g_iReply = -1;
  123.  
  124.     return dwDefaultButton;
  125. }
  126.  
  127.  
  128.  
  129.  
  130. //-----------------------------------------------------------------------------
  131. // Name: DirectXSetupCallbackFunction()
  132. // Desc: Handle each reason for why the callback was called, filtering each
  133. //       message by what the current state of g_fStatus is.
  134. //-----------------------------------------------------------------------------
  135. DWORD WINAPI DirectXSetupCallbackFunction( DWORD dwReason, DWORD dwMsgType, 
  136.                                            LPSTR strMessage, LPSTR strName, 
  137.                                            VOID* pInfo )
  138. {
  139.     if( strMessage == NULL && strName == NULL )
  140.         return IDOK;
  141.  
  142.     SetButtons( g_hDlg, -1 );
  143.     if( g_dwStatus == SHOW_ALL )
  144.     {
  145.         // Show all messages from DirectSetup
  146.         
  147.         SetWindowText( GetDlgItem( g_hDlg, ID_MYMESSAGE ), strMessage );
  148.  
  149.         // When dwMsgType is equal to zero we can display status information but
  150.         // should not wait for input from the user. 
  151.         if( dwMsgType == 0 )
  152.         {
  153.             Sleep(1000);
  154.             return IDOK;
  155.         }
  156.  
  157.         SetButtons( g_hDlg, dwMsgType );
  158.     }
  159.     else if( g_dwStatus == SHOW_UPGRADES )
  160.     {
  161.         // Show only upgrade messages
  162.  
  163.         switch( dwReason )
  164.         {
  165.             case DSETUP_CB_MSG_SETUP_INIT_FAILED:
  166.             case DSETUP_CB_MSG_INTERNAL_ERROR:
  167.             case DSETUP_CB_MSG_OUTOFDISKSPACE:
  168.             case DSETUP_CB_MSG_FILECOPYERROR:
  169.                 SetWindowText( GetDlgItem( g_hDlg, ID_MYMESSAGE ), strMessage );
  170.                 SetButtons( g_hDlg, dwMsgType );
  171.                 break;
  172.  
  173.             case DSETUP_CB_MSG_CHECK_DRIVER_UPGRADE:
  174.             {
  175.                 // pInfo points to a structure containing flags that summarize
  176.                 // the DirectXSetup functions recommendation on how the upgrade
  177.                 // of DirectX components and drivers should be preformed
  178.                 DWORD dwUpgrade = ( ((DSETUP_CB_UPGRADEINFO*)pInfo)->UpgradeFlags
  179.                                                     & DSETUP_CB_UPGRADE_TYPE_MASK );
  180.                 switch( dwUpgrade )
  181.                 {
  182.                     case DSETUP_CB_UPGRADE_FORCE:
  183.                     case DSETUP_CB_UPGRADE_KEEP:
  184.                     case DSETUP_CB_UPGRADE_SAFE:
  185.                     case DSETUP_CB_UPGRADE_UNKNOWN:
  186.                         SetWindowText( GetDlgItem( g_hDlg, ID_MYMESSAGE ), strMessage );
  187.                         SetButtons( g_hDlg, dwMsgType );
  188.                         break;
  189.                 }
  190.                 break;
  191.             }
  192.  
  193.             default:
  194.                 return IDOK;
  195.         }
  196.     }
  197.     else if( g_dwStatus == SHOW_PROBLEMS )
  198.     {
  199.         // Show only problem messages
  200.  
  201.         switch( dwReason )
  202.         {
  203.             case DSETUP_CB_MSG_CANTINSTALL_UNKNOWNOS:
  204.             case DSETUP_CB_MSG_CANTINSTALL_NT:
  205.             case DSETUP_CB_MSG_CANTINSTALL_BETA:
  206.             case DSETUP_CB_MSG_CANTINSTALL_NOTWIN32:
  207.             case DSETUP_CB_MSG_CANTINSTALL_WRONGLANGUAGE:
  208.             case DSETUP_CB_MSG_CANTINSTALL_WRONGPLATFORM:
  209.             case DSETUP_CB_MSG_PREINSTALL_NT:
  210.             case DSETUP_CB_MSG_NOTPREINSTALLEDONNT:
  211.             case DSETUP_CB_MSG_SETUP_INIT_FAILED:
  212.             case DSETUP_CB_MSG_INTERNAL_ERROR:
  213.             case DSETUP_CB_MSG_OUTOFDISKSPACE:
  214.             case DSETUP_CB_MSG_FILECOPYERROR:
  215.                 SetWindowText( GetDlgItem( g_hDlg, ID_MYMESSAGE ), strMessage );
  216.                 SetButtons( g_hDlg, dwMsgType );
  217.                 break;
  218.  
  219.             case DSETUP_CB_MSG_CHECK_DRIVER_UPGRADE:
  220.             {
  221.                 DWORD dwUpgrade = ( ((DSETUP_CB_UPGRADEINFO*)pInfo)->UpgradeFlags
  222.                                                     & DSETUP_CB_UPGRADE_TYPE_MASK );
  223.                 switch( dwUpgrade )
  224.                 {
  225.                     case DSETUP_CB_UPGRADE_FORCE:
  226.                     case (DSETUP_CB_UPGRADE_SAFE & DSETUP_CB_UPGRADE_HASWARNINGS):
  227.                     case DSETUP_CB_UPGRADE_UNKNOWN:
  228.                         SetWindowText( GetDlgItem( g_hDlg, ID_MYMESSAGE ), strMessage );
  229.                         SetButtons( g_hDlg, dwMsgType );
  230.                         break;
  231.  
  232.                     case DSETUP_CB_UPGRADE_KEEP:
  233.                         return IDOK;
  234.  
  235.                     case DSETUP_CB_UPGRADE_SAFE:
  236.                         switch( dwMsgType & 0x0000000F )
  237.                         {
  238.                             case MB_YESNO:
  239.                             case MB_YESNOCANCEL:
  240.                                 return IDYES;
  241.  
  242.                             case MB_OKCANCEL:
  243.                             case MB_OK:
  244.                             default:
  245.                                 return IDOK;
  246.                         }
  247.                         break;
  248.                 }
  249.                 break;
  250.             }
  251.  
  252.             default:
  253.                 return IDOK;
  254.         }
  255.     }
  256.     else if( g_dwStatus == SHOW_NONE )
  257.     {
  258.         // Don't show any messages
  259.         return IDOK;
  260.     }
  261.  
  262.     return GetReply( dwMsgType );
  263. }
  264.  
  265.  
  266.  
  267.  
  268. //-----------------------------------------------------------------------------
  269. // Name: DirectXGetVersion()
  270. // Desc: Shows the results of a call to DirectXSetupGetVersion()
  271. //-----------------------------------------------------------------------------
  272. VOID DirectXGetVersion()
  273. {
  274.     DWORD   dwVersion;
  275.     DWORD   dwRevision;
  276.  
  277.     INT iRetCode = DirectXSetupGetVersion( &dwVersion, &dwRevision );
  278.     // Use HIWORD(dwVersion); to get the DirectX major version
  279.     // Use LOWORD(dwVersion); to get the DirectX minor version
  280.     // For example: for DirectX 5 dwVersion == 0x00040005
  281.  
  282.     CHAR strBuf[128];
  283.     sprintf( strBuf, "Version 0x%08lX\nRevision %ld", dwVersion, dwRevision );
  284.     MessageBox( NULL, strBuf, "Results:", MB_OK|MB_ICONINFORMATION );
  285. }
  286.  
  287.  
  288.  
  289.  
  290. //-----------------------------------------------------------------------------
  291. // Name: DirectXInstall()
  292. // Desc: Set up the callback function for DirectXSetup and handle the return
  293. //       results.  This function starts a modeless version of MessageBox() so
  294. //       that the user can see the progress of the DirectX installation.
  295. //-----------------------------------------------------------------------------
  296. BOOL DirectXInstall( HWND hWnd )
  297. {
  298.     CHAR  strSource[_MAX_PATH];
  299.     CHAR  string[256];
  300.     INT   iRetCode;
  301.     DWORD dwFlags;
  302.  
  303.     // The DSETUP DLLs should be at the current path, along with the DirectX
  304.     // redist directory so that it can be found and set up.  Otherwise, change
  305.     // the code below to reflect the real path.
  306.     GetCurrentDirectory( _MAX_PATH, strSource );
  307.  
  308.     // If the user wants any messages, bring up the simulated MessageBox
  309.     // dialog
  310.     if( g_dwStatus != SHOW_NONE )
  311.     {
  312.         // Create a modeless dialog box so we can show messages that don't
  313.         // need user input
  314.         g_hDlg = CreateDialog( g_hInstance, "INSTDX", hWnd, (DLGPROC)DlgProc );
  315.         if( g_hDlg == NULL )
  316.         {
  317.             CHAR buf[200];
  318.             LoadString( g_hInstance, STR_NODIALOG, buf, 200 );
  319.             MessageBox( hWnd, string, g_strAppTitle, MB_ICONSTOP|MB_OK );
  320.             return FALSE;
  321.         }
  322.  
  323.         ShowWindow( GetDlgItem( g_hDlg, IDBUT1 ), SW_HIDE );
  324.         ShowWindow( GetDlgItem( g_hDlg, IDBUT2 ), SW_HIDE );
  325.         ShowWindow( GetDlgItem( g_hDlg, IDBUT3 ), SW_HIDE );
  326.         ShowWindow( g_hDlg, SW_NORMAL );
  327.     }
  328.  
  329.     // Set the callback function up before calling DirectXSetup
  330.     DirectXSetupSetCallback( (DSETUP_CALLBACK)DirectXSetupCallbackFunction );
  331.     if( g_dwStatus != SHOW_NONE )
  332.     {
  333.         LoadString( g_hInstance, STR_STARTSETUP, string, 256 );
  334.         SetWindowText( GetDlgItem( g_hDlg, ID_MYMESSAGE ), string );
  335.         SetButtons( g_hDlg, -1 );
  336.         Sleep( 1000 );
  337.     }
  338.  
  339.     //-------------------------------------------------------------------------
  340.     // IMPORTANT NOTE: We are about to do the DirectXSetup, but only in test
  341.     // mode. In the real world, you would remove the DSETUP_TESTINSTALL
  342.     //-------------------------------------------------------------------------
  343.     dwFlags = DSETUP_DIRECTX | DSETUP_TESTINSTALL;
  344.     if( g_bCheckOlder == TRUE )
  345.          dwFlags |= DSETUP_USEROLDERFLAG;
  346.  
  347.     iRetCode = DirectXSetup( hWnd, strSource, dwFlags );
  348.  
  349.     // If the user didn't want any message, we now need to bring up the dialog
  350.     // to reflect the return message from DirectXSetup
  351.     if( g_dwStatus == SHOW_NONE )
  352.     {
  353.         g_hDlg = CreateDialog( g_hInstance, "INSTDX", hWnd, (DLGPROC)DlgProc );
  354.         if( g_hDlg == NULL )
  355.         {
  356.             CHAR buf[200];
  357.             LoadString( g_hInstance, STR_NODIALOG, buf, 200 );
  358.             MessageBox( hWnd, string, g_strAppTitle, MB_ICONSTOP|MB_OK );
  359.             return FALSE;
  360.         }
  361.  
  362.         ShowWindow( GetDlgItem( g_hDlg, IDBUT1 ), SW_HIDE );
  363.         ShowWindow( GetDlgItem( g_hDlg, IDBUT2 ), SW_HIDE );
  364.         ShowWindow( GetDlgItem( g_hDlg, IDBUT3 ), SW_HIDE );
  365.         ShowWindow( g_hDlg, SW_NORMAL );
  366.     }
  367.  
  368.     switch( iRetCode )
  369.     {
  370.         // Since our MessageBox dialog is still up, display the results in it
  371.         case DSETUPERR_NEWERVERSION:
  372.             MessageBox( NULL, "Installation is newer than one being installed",
  373.                         "DirectX Setup", MB_OK );
  374.             break;
  375.  
  376.         case DSETUPERR_SUCCESS_RESTART:
  377.             LoadString( g_hInstance, STR_RESTART, string, 256 );
  378.             SetWindowText( GetDlgItem( g_hDlg, ID_MYMESSAGE ), string );
  379.             SetButtons( g_hDlg, -1 );
  380.             SetButtons( g_hDlg, MB_YESNO );
  381.             if( GetReply( MB_YESNO ) == IDYES )
  382.             {
  383.                 // Restart Windows
  384.                 ExitWindowsEx( EWX_REBOOT, 0 );
  385.             }
  386.             break;
  387.  
  388.         case DSETUPERR_SUCCESS:
  389.             LoadString( g_hInstance, STR_SUCCESS, string, 256 );
  390.             SetWindowText( GetDlgItem( g_hDlg, ID_MYMESSAGE ), string );
  391.             SetButtons( g_hDlg, -1 );
  392.             SetButtons( g_hDlg, MB_OK );
  393.             GetReply( MB_OK );
  394.             break;
  395.  
  396.         case DSETUPERR_BADWINDOWSVERSION:
  397.         case DSETUPERR_SOURCEFILENOTFOUND:
  398.         case DSETUPERR_BADSOURCESIZE:
  399.         case DSETUPERR_BADSOURCETIME:
  400.         case DSETUPERR_NOCOPY:
  401.         case DSETUPERR_OUTOFDISKSPACE:
  402.         case DSETUPERR_CANTFINDINF:
  403.         case DSETUPERR_CANTFINDDIR:
  404.         case DSETUPERR_INTERNAL:
  405.         case DSETUPERR_UNKNOWNOS:
  406.         case DSETUPERR_USERHITCANCEL:
  407.         case DSETUPERR_NOTPREINSTALLEDONNT:
  408.             LoadString( g_hInstance, STR_ERRORRETURN + (iRetCode * -1) - 1, string, 256 );
  409.             SetWindowText( GetDlgItem( g_hDlg, ID_MYMESSAGE ), string );
  410.             SetButtons( g_hDlg, -1 );
  411.             SetButtons( g_hDlg, MB_OK );
  412.             GetReply( MB_OK );
  413.             break;
  414.     }
  415.  
  416.     DestroyWindow( g_hDlg );
  417.     g_hDlg = NULL;
  418.  
  419.     return TRUE;
  420. }
  421.